/**
 *
 * @author Doan Tuan Anh
 */

import java.util.Timer;
import java.util.Random;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.TiledLayer;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;

import java.io.IOException;

public class MyGameCanvas extends GameCanvas {
	        
    static final int GROUND_HEIGHT = 30;
    static final int CORNER_X = 0;
    static final int CORNER_Y = 0;
    static int DISP_WIDTH;
    static int DISP_HEIGHT;
    static int FONT_HEIGHT;
    static Font FONT;

    static int SCORE_WIDTH;
    static int TIME_WIDTH;
    public static final int BLACK = 0;
    public static final int WHITE = 0xffffff;

    private Display myDisplay;
    private GameMidlet gameMidlet;
    private GameLayerManager layerManager;
    private boolean myGameOver;
    private int myScore = 0;
    private int myInitialGameTicks = 950;
    private int myOldGameTicks = myInitialGameTicks;
    private int myGameTicks = myOldGameTicks;
    private static String myInitialString = "1:00";
    private String myTimeString = myInitialString;

      void setGameOver() {
        myGameOver = true;
        gameMidlet.userPauseThreads();
      }

      GameLayerManager getLayerManager()
      {
          return layerManager;
      }

      Piranha[] getPiranhas()
      {
          return layerManager.getPiranhas();
      }

      ClownFish[] getClownFishes() {
        return layerManager.getClownFishes();
      }

      GoldFish[] getGoldFishes()
      {
          return layerManager.getGoldFishes();
      }

      Heart[] getHearts()
      {
          return layerManager.getHearts();
      }


      private Image originalImage, background;

      public MyGameCanvas(GameMidlet midlet) throws Exception {
        super(false);
        myDisplay = Display.getDisplay(midlet);
        gameMidlet = midlet;
   
        DISP_WIDTH = getWidth();
        DISP_HEIGHT = getHeight();
        
        
        Display disp = Display.getDisplay(gameMidlet);
        if(disp.numColors() < 256) {
          throw(new Exception("game requires 256 shades"));
        }
        if((DISP_WIDTH < 150) || (DISP_HEIGHT < 170)) {
          throw(new Exception("Screen too small"));
        }

        FONT = getGraphics().getFont();
        FONT_HEIGHT = FONT.getHeight();
        SCORE_WIDTH = FONT.stringWidth("Score: 000");
        TIME_WIDTH = FONT.stringWidth("Time: " + myInitialString);

        if(layerManager == null) {
            
            layerManager = new GameLayerManager(CORNER_X, CORNER_Y, DISP_WIDTH, DISP_HEIGHT);
        } 
        
        originalImage = Image.createImage("/background.png");
        background = resizeImage(originalImage, DISP_WIDTH, DISP_HEIGHT);
         
      }
      
      Image resizeImage(Image image, int resizedWidth, int resizedHeight) {  
          int[] in = null, out = null;  

          int width = image.getWidth(), height = image.getHeight();  
          in = new int[width];   

          int i  =0;  
          int dy, dx;   
          out = new int[resizedWidth * resizedHeight];   

          for (int y = 0; y < resizedHeight; y++)   
          {   
            dy = y * height / resizedHeight;  

            image.getRGB(in,0,width,0,dy,width,1);   


            for (int x = 0; x < resizedWidth; x++)   
            {   
              dx = x * width / resizedWidth;   

              out[(resizedWidth * y) + x] = in[dx];  
            }   
          }   
          Image resized = Image.createRGBImage(out,resizedWidth,resizedHeight,true);  
          return resized;   
      }  
     
      void start() {
        myGameOver = false;
        myDisplay.setCurrent(this);
        repaint();
      }

      void reset() {
        layerManager.reset();
        myScore = 0;
        myGameOver = false;
        myGameTicks = myInitialGameTicks;
        myOldGameTicks = myInitialGameTicks;
        
        repaint();
      }

      void flushKeys() {
        getKeyStates();
      }

      protected void hideNotify() {
        try {
          gameMidlet.systemPauseThreads();
        } catch(Exception oe) {

        }
      }

      protected void showNotify() {
        try {
          gameMidlet.systemStartThreads();
        } catch(Exception oe) {

        }
      }
      
    protected void pointerPressed(int x, int y)
    {
        Duck duck = layerManager.getDuck();

        if(duck.isRunning()) return;

        if(duck.isDiving()) return;

        if(x > duck.getRefPixelX()) duck.setOrient(true);
        else duck.setOrient(false);

        if(duck.getInitialY() > y + 10) return;


        if(Math.abs(duck.getInitialY() - y) <= 20)
        {
            duck.setRunning(x);
            return;
        }

        layerManager.startWaterSound();

        duck.setDiving(x, y);
    }
    
      void setSize()
      {
          DISP_WIDTH = getWidth();
          DISP_HEIGHT = getHeight();
          
          layerManager.getDuck().setWidth(DISP_WIDTH);
          layerManager.getDuck().setHeight(DISP_HEIGHT);
              
          Heart[] heart = getHearts();
          
          heart[0].setRefPixelPosition(DISP_WIDTH - 120, 15);
          heart[1].setRefPixelPosition(DISP_WIDTH - 95, 15);
          heart[2].setRefPixelPosition(DISP_WIDTH - 70, 15);
          heart[3].setRefPixelPosition(DISP_WIDTH - 45, 15);
          heart[4].setRefPixelPosition(DISP_WIDTH - 20, 15);
      }
      
      public void paint(Graphics g) {
        boolean changedOrientation = false;
        
        if(DISP_WIDTH != getWidth()) 
        {
            changedOrientation = true;
            setSize();
        }
        
        g.setColor(WHITE);
        g.fillRect(CORNER_X, CORNER_Y, DISP_WIDTH, DISP_HEIGHT);
        
        if(changedOrientation) background = resizeImage(originalImage, DISP_WIDTH, DISP_HEIGHT);
        
        g.drawImage(background, getWidth(), getHeight(), g.BOTTOM| g.RIGHT);
        
        try {
          layerManager.setWidth(DISP_WIDTH); //add
          layerManager.setHeight(DISP_HEIGHT); //add
          
          layerManager.paint(g);
        } catch(Exception e) {

        }
        g.setColor(BLACK);
        g.setFont(FONT);
        g.drawString("Score: " + myScore, CORNER_X + 10, CORNER_Y + FONT_HEIGHT / 2, g.TOP | g.LEFT);
        
        if(myGameOver) {
          gameMidlet.setNewCommand();
          int goWidth = FONT.stringWidth("GAME OVER");
          g.setColor(BLACK);
          g.setFont(FONT);
          g.drawString("GAME OVER", (DISP_WIDTH - goWidth) / 2, 
                       CORNER_Y + FONT_HEIGHT, g.TOP|g.LEFT);
          g.drawString("Score: " + myScore, CORNER_X + 10, CORNER_Y + FONT_HEIGHT / 2, g.TOP | g.LEFT);
        }
      }

      void advance() {
        myScore += layerManager.advance(myGameTicks);

        Heart[] hearts = getHearts();
        boolean alive = false;
        for(int i = 0; i < hearts.length; i++) alive |= hearts[i].isVisible();
        
        if(!alive)
        {
            layerManager.getDuck().setVisible(true);
            setGameOver();
        }
        try {
          paint(getGraphics());
          flushGraphics();
        } catch(Exception e) {

        }
      }
}